/**
 * 
 */
package lu.med.praxiswahl.wahlumed.client.utilities;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * @author PatrickPierre
 * 
 */
public class XMLReader {

	private static XMLReader tableConfigInstance = null;

	private static XMLReader pathConfigInstance = null;

	private static XMLReader inputConfigInstance = null;

	private static XMLReader printConfigInstance = null;
	
	private static XMLReader widthConfigInstance = null;
	

	private Document doc;
	private File file;

	private XMLReader(File file) {

		this.file = file;
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder;
		try {
			dBuilder = dbFactory.newDocumentBuilder();
			doc = dBuilder.parse(file);
			doc.getDocumentElement().normalize();

		} catch (ParserConfigurationException | SAXException | IOException e) {
			e.printStackTrace();
		}

	}

	public static XMLReader getTableConfigXMLReaderInstance(File file) {

		if (tableConfigInstance == null) {
			tableConfigInstance = new XMLReader(file);
		}
		return tableConfigInstance;
	}

	public static XMLReader getInputConfigXMLReaderInstance(File file) {

		if (inputConfigInstance == null) {
			inputConfigInstance = new XMLReader(file);
		}
		return inputConfigInstance;
	}

	public static XMLReader getPathConfigXMLReaderInstance(File file) {

		if (pathConfigInstance == null) {
			pathConfigInstance = new XMLReader(file);
		}
		return pathConfigInstance;
	}

	public static XMLReader getPrintConfigXMLReaderInstance(File file) {

		if (printConfigInstance == null) {
			printConfigInstance = new XMLReader(file);
		}
		return printConfigInstance;
	}
	
	public static XMLReader getWidthConfigXMLReaderInstance(File file) {

		if (widthConfigInstance == null) {
			widthConfigInstance = new XMLReader(file);
		}
		return widthConfigInstance;
	}
	

	public String getValue(String tag, Element element) {
		NodeList nodes = element.getElementsByTagName(tag).item(0)
				.getChildNodes();
		Node node = (Node) nodes.item(0);
		return node.getNodeValue();
	}

	public Document getDoc() {
		return doc;
	}

	public void setDoc(Document doc) {
		this.doc = doc;
	}

	public NodeList retrieveDocumentNodeList(String tag) {
		return doc.getElementsByTagName(tag);
	}

	public String retrieveRoot() {
		return doc.getDocumentElement().getNodeName();
	}

	public void updateDocument() {

		TransformerFactory transformerFactory = TransformerFactory
				.newInstance();
		try {
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(this.getDoc());

			StreamResult result = new StreamResult(new File(
					"../tableConfigurations.xml"));
			transformer.transform(source, result);

		} catch (TransformerConfigurationException e) {

			e.printStackTrace();
		} catch (TransformerException e) {

			e.printStackTrace();
		}
	}

	public void resetValueOfDeepedTag(String configTag, String deepedTag,
			String deepedTagNewNodeValue) {
		Node configTagNode = getDoc().getElementsByTagName(configTag).item(0);
		NodeList configTagChildNodes = configTagNode.getChildNodes();

		for (int i = 0; i < configTagChildNodes.getLength(); i++) {
			Node node = configTagChildNodes.item(i);

			if (node.getNodeType() == Node.ELEMENT_NODE
					&& node.getNodeName().equals(deepedTag)) {
				node.getChildNodes().item(0)
						.setNodeValue(deepedTagNewNodeValue);
				break;
			} else {
//				System.out.println("was not " + deepedTag + " IN ::"
//						+ configTag);
			}

		}
	}
}
